#include <bits/stdc++.h>
#include <mutex>
using namespace std;
#define maxn 10
mutex m;
condition_variable full_con; //缓冲池已满，让full_con等待
condition_variable empty_con; //缓冲池为空，让empty等待
string buf[maxn]; //建立能容纳maxn个的缓冲池
int pro_num = 0; //记录生产者在缓冲池的位置
int con_num = 0; //记录消费者在缓冲池的位置
int pro_idx = 0; //记录第几个被生产者生产的商品
class producer {
private:
    string in; // 生产的产品
    int idx; // 标记现在是第几个生产者
public:
    producer(string in = "", int idx = 0) : in(in), idx(idx) {}
    ~producer() = default;

    void produce() {
        in = "生产者" + to_string(this->idx) + "生产产品" + to_string(pro_idx++);
        unique_lock<mutex> lock(m);
        while ((pro_num + 1) % maxn == con_num) {
            cout << "缓冲池已满，生产者 " << idx << " 在等待一个空位" << endl;
            full_con.wait(lock);
        }
        buf[pro_num] = in;
        pro_num = (pro_num + 1) % maxn;
        cout << in << endl;
        empty_con.notify_all(); //唤醒empty
    }
};

class consumer {
private:
    string out;
    int idx;
public:
    consumer(string out = "",int idx = 0) : out(out) , idx(idx){}
    ~consumer() = default;
    void consume() {
        unique_lock<mutex> lock(m);
        while (pro_num == con_num) {
            cout << "缓冲池为空，消费者" << idx << "在等待商品" << endl;
            empty_con.wait(lock);
        }
        out = "消费者" + to_string(this->idx) + "消费了" + buf[con_num]; //消费者消费了产品
        con_num = (con_num + 1) % maxn;
        cout << out << endl;
        full_con.notify_all(); // 唤醒full
    }
};
void producer_work(producer p) { //生产者生产50次产品
    int i = 0;
    while(i < 50){
        p.produce();i++;
    }
}
void consumer_work(consumer c) { //消费者消费50次产品
    int i = 0;
    while (i < 50) {
        c.consume();i++;
    }
}
int main()
{
    producer p;
    consumer c;
    thread pro(producer_work, p);
    thread con(consumer_work, c);
    pro.join();
    con.join();
    return 0;
}